package com.sais.manage.boot.building.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sais.manage.boot.building.asy.AsyCreateRoom;
import com.sais.manage.boot.building.asy.BatchBindRoomUser;
import com.sais.manage.boot.building.dto.BatchRoomUser;
import com.sais.manage.boot.building.dto.BatchRoomUserConfig;
import com.sais.manage.boot.building.dto.BuildingDTO;
import com.sais.manage.boot.building.dto.RoomBatchSaveDTO;
import com.sais.manage.boot.building.dto.RoomDTO;
import com.sais.manage.boot.building.dto.RoomSaveDTO;
import com.sais.manage.boot.building.dto.RoomSearchDTO;
import com.sais.manage.boot.building.dto.UserRoomDTO;
import com.sais.manage.boot.building.entity.Room;
import com.sais.manage.boot.building.exception.BuildingException;
import com.sais.manage.boot.building.mapper.BuildingMapper;
import com.sais.manage.boot.building.mapper.RoomMapper;
import com.sais.manage.boot.building.service.IRoomService;
import com.sais.common.utils.UUIDUtils;
import com.sais.manage.boot.platform.dto.UserDTO;
import com.sais.manage.boot.platform.dto.UserInfoDTO;
import com.sais.manage.boot.platform.entity.User;
import com.sais.manage.boot.platform.mapper.UserInfoMapper;
import com.sais.manage.boot.platform.mapper.UserMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 宿舍管理系统-房间 service 实现类
 *
 * @author zhang
 * @date 2019/11/30
 **/
@Service
@Slf4j
public class RoomServiceImpl implements IRoomService {


    @Resource
    private RoomMapper roomMapper;

    @Resource
    private BuildingMapper buildingMapper;

    @Resource
    private AsyCreateRoom createRoom;

    @Resource
    private UserInfoMapper userInfoMapper;

    @Resource
    private UserMapper userMapper;

    @Resource
    private BatchBindRoomUser batchBindRoomUser;

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public boolean saveRoom(RoomSaveDTO roomSaveDTO) {
        String ukId = roomSaveDTO.getUkId();
        if (StringUtils.isEmpty(ukId)) {
            createRoom(roomSaveDTO);
        } else {
            updateRoom(roomSaveDTO);
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public boolean createRoom(RoomSaveDTO roomSaveDTO) {
        Room room = roomSaveDTO.convert();
        room.setUkId(UUIDUtils.getLower());
        // 添加房间信息
        roomMapper.createRoom(room);
        return true;
    }


    @Override
    @Transactional(rollbackFor = {Exception.class})
    public boolean updateRoom(RoomSaveDTO roomSaveDTO) {
        Room room = roomSaveDTO.convert();
        room.setGmtModified(LocalDateTime.now());
        roomMapper.updateById(roomSaveDTO.convert());
        return true;

    }


    @Override
    @Transactional(rollbackFor = {Exception.class})
    public boolean deleteRoom(String roomId) {
        RoomDTO roomDTO = selectRoom(roomId);
        if (roomDTO.getBuildingType() - roomDTO.getCount() > 0) {
            throw new BuildingException(BuildingException.ROOM_NOT_NULL);
        }
        roomMapper.deleteRoom(roomId);
        return true;
    }


    @Override
    public RoomDTO selectRoom(String roomId) {
        RoomDTO roomDTO = roomMapper.selectRoom(roomId);
        return roomDTO;
    }


    @Override
    public Page<RoomDTO> listRoom(Integer current, Integer size, RoomSearchDTO roomSearchDTO) {
        Page<RoomDTO> page = new Page<>(current, size);
        return roomMapper.listRoom(page, roomSearchDTO);
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public boolean batchSaveRoom(RoomBatchSaveDTO roomBatchSaveDTO) {
        Integer layer = roomBatchSaveDTO.getLayer();
        if (layer < 1 || layer > 99) {
            throw new BuildingException(BuildingException.ROOM_LAY);
        }

        String buildingId = roomBatchSaveDTO.getBuildingId();
        if (StringUtils.isEmpty(buildingId)) {
            throw new BuildingException(BuildingException.BUILDING_NULL);
        }
        BuildingDTO buildingDTO = buildingMapper.selectBuilding(buildingId);

        Integer startLayer = roomBatchSaveDTO.getStartLayer();

        for (Integer i = startLayer; i <= layer; i++) {
            createRoom.createRoom(buildingDTO, roomBatchSaveDTO, i);
        }

        return true;
    }

    @Override
    public List<RoomDTO> listRoomByBuildingId(String buildingId) {
        List<RoomDTO> rooms = roomMapper.listRoomByBuildingId(buildingId);
        return rooms;
    }

    @Override
    public UserRoomDTO selectRoomByUserId(String userId) {
        UserRoomDTO userRoom = roomMapper.selectRoomByUserId(userId);
        return userRoom;
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public boolean batchBindRoomUser(BatchRoomUser batchRoomUser) {
        List<User> users = batchRoomUser.getUsers();

        BatchRoomUserConfig boy = batchRoomUser.getBoy();
        BatchRoomUserConfig girl = batchRoomUser.getGirl();

        //根据宿舍楼id 查询该宿舍楼下所有可住房间,若选择了起始房间，做房间限制
        List<RoomDTO> boyRooms = null;
        if (!StringUtils.isEmpty(boy)) {
            if (!StringUtils.isEmpty(boy.getRoomNum())) {
                RoomDTO room = roomMapper.selectRoom(boy.getRoomNum());
                boyRooms = roomMapper.listLimitAvailRoom(boy.getBuildingNum(), room.getCode());
            } else {
                boyRooms = roomMapper.listAvailRoom(boy.getBuildingNum());
            }
        }

        List<RoomDTO> girlRooms = null;
        if (!StringUtils.isEmpty(girl)) {
            if (StringUtils.isEmpty(girl.getRoomNum())) {
                RoomDTO room = roomMapper.selectRoom(girl.getRoomNum());
                girlRooms = roomMapper.listLimitAvailRoom(girl.getBuildingNum(), room.getCode());
            } else {
                girlRooms = roomMapper.listAvailRoom(girl.getBuildingNum());
            }
        }

        List<UserDTO> girlUsers = new ArrayList<>();
        List<UserDTO> boyUsers = new ArrayList<>();

        for (User user : users) {
            UserDTO userDTO = userMapper.selectUser(user.getUkId());
            UserInfoDTO userInfo = userInfoMapper.selectUserInfo(user.getUkId());
            if (!StringUtils.isEmpty(userInfo)) {
                if ("1".equals(userInfo.getGender())) {
                    boyUsers.add(userDTO);
                } else if ("0".equals(userInfo.getGender())) {
                    girlUsers.add(userDTO);
                }
            }
        }

        if (!CollectionUtils.isEmpty(boyUsers)) {
            batchBindRoomUser.batchBindRoomUser(boyRooms, boyUsers);
        }
        if (!CollectionUtils.isEmpty(girlUsers)) {
            batchBindRoomUser.batchBindRoomUser(girlRooms, girlUsers);
        }

        return true;
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public boolean batchUnBindRoomUser(List<User> users) {
        //批量删除用户  同时删除相关的房间详细
        userMapper.batchDeleteUser(users);
        roomMapper.batchUnBindRoomUser(users);
        return true;
    }
}
